'use strict'

/**
 * 方法类
 */
//------------------------------------------------------------------
import dayjs from 'dayjs'
import crypto from 'crypto-js'
//------------------------------------------------------------------

/**
 * 单向加密
 *
 * @param m 加密方法
 * @param val 加密对象
 * @param upper 结果是否转大写
 */
const cryptoInner = (m, val, upper = false) => {
  let res = m(val).toString()
  if (upper) {
    res = res.toUpperCase()
  }
  return res
}

/**
 * MD5加密
 *
 * @param val 加密对象
 * @param upper 结果是否转大写
 */
const md5 = (val, upper = false) => {
  let { MD5 } = crypto
  return cryptoInner(MD5, val, upper)
}

/**
 * SHA1加密
 *
 * @param val 加密对象
 * @param upper 结果是否转大写
 */
const sha1 = (val, upper = false) => {
  let { SHA1 } = crypto
  return cryptoInner(SHA1, val, upper)
}

/**
 * 字符串格式化
 * ("{0}, {1}", "a", "b") -> "a, b"
 */
const formatString = (val, ...params) => {
  let res = val
  for (let i = 0; i < params.length; i++) {
    res = res.replace(RegExp('\\{' + i + '\\}', 'ig'), params[i])
  }
  return res
}

/**
 * 字符串格式化
 * ("{a}, {b}", { a: 'x', b: 'y' }) -> "x, y"
 */
const formatString2 = (val, params) => {
  let res = val
  for (let key in params) {
    res = res.replace(RegExp('\\{' + key + '\\}', 'ig'), params[key])
  }
  return res
}

/**
 * 范围随机数
 *
 * @param from 随机数范围from
 * @param to 随机数范围to
 */
const randomRange = (from, to) => {
  return Math.floor(Math.random() * (to - from) + from)
}

/**
 * 数值随机数(指定长度)
 *
 * @param length 长度
 */
const randomNum = (length) => {
  let val
  while ((val = Math.random()) < 0.1) {
    // 防止出现0.0X类型的随机数，导致结果位数不正确
  }
  return Math.floor(val * Math.pow(10, length))
}

/**
 * 格式化日期
 *
 * @param date 日期
 * @param format 格式
 */
const formatDate = (date, format) => {
  if (!date) return ''
  return dayjs(date).format(format)
}

/**
 * 格式化年月日
 *
 * @param date 日期
 */
const formatYmd = (date) => {
  return formatDate(date, 'YYYYMMDD')
}

/**
 * 格式化年月日(有格式)
 *
 * @param date 日期
 */
const formatYmdF = (date) => {
  return formatDate(date, 'YYYY-MM-DD')
}

/**
 * 格式化年月日时分
 *
 * @param date 日期
 */
const formatYmdhm = (date) => {
  return formatDate(date, 'YYYYMMDDHHmm')
}

/**
 * 格式化年月日时分(有格式)
 *
 * @param date 日期
 * @param l2 两行显示
 */
const formatYmdhmF = (date, l2 = false) => {
  if (l2) {
    return formatDate(date, 'YYYY-MM-DD\nHH:mm')
  } else {
    return formatDate(date, 'YYYY-MM-DD HH:mm')
  }
}

/**
 * 格式化年月日时分秒
 *
 * @param date 日期
 */
const formatYmdhms = (date) => {
  return formatDate(date, 'YYYYMMDDHHmmss')
}

/**
 * 格式化年月日时分秒(有格式)
 *
 * @param date 日期
 * @param l2 两行显示
 */
const formatYmdhmsF = (date, l2 = false) => {
  if (l2) {
    return formatDate(date, 'YYYY-MM-DD\nHH:mm:ss')
  } else {
    return formatDate(date, 'YYYY-MM-DD HH:mm:ss')
  }
}

/**
 * 格式化时分
 *
 * @param date 日期
 */
const formatHm = (date) => {
  return formatDate(date, 'HHmm')
}

/**
 * 格式化时分(有格式)
 *
 * @param date 日期
 */
const formatHmF = (date) => {
  return formatDate(date, 'HH:mm')
}

/**
 * 格式化时分秒
 *
 * @param date 日期
 */
const formatHms = (date) => {
  return formatDate(date, 'HHmmss')
}

/**
 * 格式化时分秒(有格式)
 *
 * @param date 日期
 */
const formatHmsF = (date) => {
  return formatDate(date, 'HH:mm:ss')
}

/**
 * 校验手机号
 */
const checkMobile = (val) => {
  return /^1[3456789]\d{9}$/.test(val)
}

/**
 * 校验Email
 */
const checkEmail = (val) => {
  return /^\w[-\w.+]*@([A-Za-z0-9][-A-Za-z0-9]*\.)+[A-Za-z]+$/.test(val)
}

/**
 * 校验URL
 */
const checkUrl = (val) => {
  return /^((https|http|ftp|rtsp|mms)?:\/\/)[^\s]+$/.test(val)
}

/**
 * 列表转对象
 *
 * @param list 列表
 * @param keyCol key字段
 * @param valCol 值字段，不设定时保存对象本身
 */
const list2Map = (list, keyCol, valCol) => {
  let res = {}
  if (!list || list.length === 0) return res
  for (let i = 0; i < list.length; i++) {
    let key = list[i][keyCol]
    if (key) {
      res[key] = valCol ? list[i][valCol] : list[i]
    }
  }
  return res
}

/**
 * 换行转<br />
 *
 * @param str 转换对象
 */
const enterToBr = (str) => {
  if (!str) {
    return ''
  } else {
    return str.split('\n').join('<br/>')
  }
}

/**
 * 解析URL参数
 *
 * @param url
 */
const getQueryVariable = (url) => {
  let params = {},
    h
  let hash = url.slice(url.indexOf('?') + 1).split('&')
  for (let i = 0; i < hash.length; i++) {
    h = hash[i].split('=')
    params[h[0]] = h[1]
  }
  return params
}

/**
 * 路由跳转
 *
 * @param router 路由实例
 * --param path 路径(可带url参数)
 * --param query 自带参数
 * --param replace 是否replace
 */
const routeUrl =
  (router) =>
  (path, query, replace = false) => {
    if (path.indexOf('?') >= 0) {
      query = getQueryVariable(path)
      path = path.split('?')[0]
    }
    return router.push({ path, query, replace })
  }

/**
 * 下载处理
 *
 * @param param 参数
 *        data 文件
 *        filename 下载文件名
 */
const download = (param) => {
  let link = document.createElement('a')
  try {
    link.href = window.URL.createObjectURL(param.data)
    link.download = param.filename
    document.body.appendChild(link)
    link.click()
  } finally {
    document.body.appendChild(link)
  }
}

/**
 * 本地存储
 *
 * @param paramKey 存储key
 * @param paramValue 存储值
 * @param local localStorage或sessionStorage
 */
const saveStorage = (paramKey, paramValue, local) => {
  let secretKey = paramKey
  let secretValue = JSON.stringify({ t: typeof paramValue, v: paramValue })
  if (local) {
    localStorage.setItem(secretKey, secretValue)
  } else {
    sessionStorage.setItem(secretKey, secretValue)
  }
}

/**
 * 获取本地存储
 *
 * @param paramKey 存储key
 */
const getStorage = (paramKey) => {
  let key = paramKey
  let secretValue = sessionStorage.getItem(key) || localStorage.getItem(key)
  if (!secretValue) return
  let val = secretValue
  try {
    val = JSON.parse(secretValue)
  } catch {
    return val
  }
  let content = null
  if (val.t === 'string') {
    content = val.v
  } else if (val.t === 'number') {
    content = Number(val.v)
  } else if (val.t === 'boolean') {
    content = eval(val.v)
  } else if (val.t === 'object') {
    content = val.v
  }
  return content
}

/**
 * 删除本地存储
 *
 * @param keyP 存储key
 */
const removeStorage = (keyP) => {
  let key = keyP
  localStorage.removeItem(key)
  sessionStorage.removeItem(key)
}

/**
 * 根据地址获取经纬度
 * @param {*} address 
 * @param {*} callback 
 */
const getLatLngByCity = (address, callback) => {
  var geocoder = new qq.maps.Geocoder()
  geocoder.getLocation(address)
  geocoder.setComplete(function (res) {
    callback(res)
  })
  geocoder.setError(function (err) {
    callback(err)
  })
}

export default {
  md5,
  sha1,
  formatString,
  formatString2,
  randomRange,
  randomNum,
  formatDate,
  formatYmd,
  formatYmdF,
  formatYmdhm,
  formatYmdhmF,
  formatYmdhms,
  formatYmdhmsF,
  formatHm,
  formatHmF,
  formatHms,
  formatHmsF,
  checkMobile,
  checkEmail,
  checkUrl,
  list2Map,
  enterToBr,
  getQueryVariable,
  routeUrl,
  download,
  saveStorage,
  getStorage,
  removeStorage,
  getLatLngByCity
}
